package Dm

import (
	"context"
	"fmt"
	"db2s/ETL"
	"db2s/global"
	"db2s/go-log/log"
	"db2s/parDef"
	"db2s/ref"
	"strings"
)

func modifyGetDbQueryOptions(s ETL.InstanceActiveS, Expect string) ETL.InstanceActiveS {
	s.SqlMode = true
	s.DBType = DBType
	s.Expect = Expect
	s.GisValFunc = QueryColValManage
	return s
}
func getTableName(schema, table any) (tableName string) {
	return fmt.Sprintf(" %v.%v ", schema, table)
}

func getLikeTable(table string) (res string) {
	switch {
	case table == "*":
		return ""
	case strings.Contains(table, "%"):
		return fmt.Sprintf("and TABLE_NAME like '%v'", table)
	default:
		return fmt.Sprintf("and TABLE_NAME = '%v'", table)
	}
}
func getLikeSeqName(table string) (res string) {
	switch {
	case table == "*":
		return ""
	case strings.Contains(table, "%"):
		return fmt.Sprintf("and SEQUENCE_NAME like '%v'", table)
	default:
		return fmt.Sprintf("and SEQUENCE_NAME = '%v'", table)
	}
}
func getSysObjectView(p ...string) (sysView []string) {
	return p
}
func generalQuerySysObjectSql(s, t string, o []string, body func(o, s, t string) string) (res []string) {
	for _, v := range o {
		res = append(res, body(v, s, t))
	}
	return
}
func newExecUpdateSql(event, schemaTable string, active any, UpdateSqlStr []string) (execTime int64, err error) {
	defer func() {
		err = ref.RecoverPanic(event, recover())
	}()
	log.MainLog().DebugS(event, schemaTable, fmt.Sprintf(" exec sql is %v.", UpdateSqlStr))
	//if active.DB == nil {
	//	err = fmt.Errorf("sql exec fail. connection point is nil")
	//	log.ErrorLog().ErrorS(event, schemaTable, fmt.Sprintf("sql exec fail. sql is %v connection point is nil", UpdateSqlStr))
	//	return
	//}
	if execTime, err = ETL.Update(active,[]string{},UpdateSqlStr); err != nil {
		log.ErrorLog().ErrorS(event, schemaTable, fmt.Sprintf("sql exec fail. exec sql is %v error is %v", UpdateSqlStr, err))
		return
	}
	log.MainLog().DebugS(event, schemaTable, fmt.Sprintf(" sql is %v, bath timeOut is %v ms.", UpdateSqlStr, execTime))
	return
}
func sqlExec(event string, schemaTable string, dbOptions any, execSqlFunc func(S any, sqlStr []string,expect string) (global.Return, error), execSql []string, expect string) (result global.Return, err error) {
	log.MainLog().DebugS(event, schemaTable, fmt.Sprintf(" sql is %v.", execSql))
	if execSqlFunc == nil {
		log.MainLog().WarnS(event, schemaTable, fmt.Sprintf(" ExecSqlFunc is nil."))
		return
	}
	if result, err = execSqlFunc(dbOptions, execSql,expect); err != nil {
		err = ref.ErrAddPrintf(event, err)
		log.ErrorLog().ErrorS(event, schemaTable, fmt.Sprintf(" sql is %v, error is %v.", result.Sql, err))
		return
	}
	log.MainLog().DebugS(event, schemaTable, fmt.Sprintf(" sql is %v, bath timeOut is %v ms,query result is %v.", result.Sql, result.TimeOut, result.Result))
	return
}
func resultExec(event string, schemaTable string, execFunc func(s any, execFunc any) (any, error), res global.Return, funcParameter any, funcDef any) (result global.Return, err error) {
	result = res
	if execFunc == nil {
		log.MainLog().WarnS(event, schemaTable, fmt.Sprintf(" ExecFunc is nil."))
		return
	}
	if result.Result, err = execFunc(funcParameter, funcDef); err != nil {
		err = ref.ErrAddPrintf(event, err)
		log.ErrorLog().ErrorS(event, schemaTable, fmt.Sprintf(" sql is %v, error is %v.", result.Sql, err))
		return
	}
	log.MainLog().DebugS(event, schemaTable, fmt.Sprintf(" sql is %v, bath timeOut is %v ms,query result is %v.", result.Sql, result.TimeOut, result.Result))
	return
}

func getExecFuncParameterValueBase(ctx context.Context) (schema, table string) {
	schema = parDef.GetParameterValueAnyToString(parDef.GetFuncParameterValue(ctx, parDef.GetSchemaParameterValue()))
	table = parDef.GetParameterValueAnyToString(parDef.GetFuncParameterValue(ctx, parDef.GetTableParameterValue()))
	return
}
func getExecSqlFuncOptionsValueBase(ctx context.Context) (res ETL.ReadOpt) {
	return parDef.GetReadDbExecOptions(parDef.GetFuncParameterValue(ctx, parDef.GetDbReadOptionsParameterValue()))
}
func getSqlExecFuncParameterValue(ctx context.Context, event string, objectView []string, body func(o string, s string, t string) string) (eventNew string, schemaTable string, dbOptions any, execSqlFunc func(S any, sqlStr []string,expect string) (global.Return, error), execSql []string, expect string) {
	var schema, table = getExecFuncParameterValueBase(ctx)
	execSql = generalQuerySysObjectSql(schema, table, getSysObjectView(objectView...), body)
	dbOptions = getExecSqlFuncOptionsValueBase(ctx)
	expect = parDef.GetParameterValueAnyToString(parDef.GetFuncParameterValue(ctx, parDef.GetExpectParameterValue()))
	//execSqlFunc = parDef.GetDbExecSqlFunc(parDef.GetFuncParameterValue(ctx, parDef.GetExecSqlFuncParameterValue()))
	return event, getTableName(schema, table), dbOptions, execSqlFunc, execSql, expect
}
func getExternalExecFuncParameterValue(ctx context.Context, event string, res global.Return, funcParameter any, funcDef any) (eventNew string, schemaTable string, externalExecFunc func(s any, execFunc any) (any, error), result global.Return, funcParameterNew any, funcDefNew any) {
	externalExecFunc = parDef.GetExternalExecFunc(parDef.GetFuncParameterValue(ctx, parDef.GetExternalExecFuncParameterValue()))
	return event, getTableName(getExecFuncParameterValueBase(ctx)), externalExecFunc, res, funcParameter, funcDef
}
func getJsonNameValue(getJsonValue func(s any, key string) (any, error), meta any, name string) (result string) {
	var rr any
	var err error
	if getJsonValue != nil {
		if rr, err = getJsonValue(meta, name); err != nil {
			return
		}
	}
	return fmt.Sprintf("%v", rr)
}
